import { Logger } from "./Logger";
export class EventManager {

    public static instance: EventManager = new EventManager();
    public handlers = {};

    public on(eventName: string, handler: Function, target: any) {
        let handlerList = this.handlers[eventName];
        if (!handlerList) {
            handlerList = [];
            this.handlers[eventName] = handlerList;
        }

        for (let i = 0; i < handlerList.length; i++) {
            if (!handlerList[i]) {
                handlerList[i].handler = handler;
                handlerList[i].target = target;
                return i;
            }
        }
        handlerList.push({ handler: handler, target: target });
        return handlerList.length;
    };

    public dispatch(eventName: string, ...restOfName: any[]) {
        let handlerList = this.handlers[eventName];
        if (!handlerList) {
            return;
        }
        // for (let i = 0; i < handlerList.length; i++) {
        for (let i = handlerList.length - 1; i >= 0; i--) {
            let handler = handlerList[i].handler;
            let target = handlerList[i].target;
            if (handler) {
                try {
                    if (target) {
                        handler.call(target, ...restOfName)
                    } else {
                        handler.call(...restOfName)
                    }
                } catch (e) {
                    console.error(e);
                }
            }
        }
    }

    public dispatchOnce(eventName: string, ...restOfName: any[]){
        let handlerList = this.handlers[eventName];
        if (!handlerList) {
            return;
        }
        // for (let i = 0; i < handlerList.length; i++) {
        for (let i = handlerList.length - 1; i >= 0; i--) {
            let handler = handlerList[i].handler;
            let target = handlerList[i].target;
            if (handler) {
                try {
                    if (target) {
                        handler.call(target, ...restOfName)
                    } else {
                        handler.call(...restOfName)
                    }
                    break;
                } catch (e) {
                    console.error(e);
                }
            }
        }
    }

    public off(eventName: string, handler: Function, target: any) {
        let handlerList = this.handlers[eventName];
        if (!handlerList) {
            return;
        }

        for (let i = 0; i < handlerList.length; i++) {
            let oldHandler = handlerList[i].handler;
            let oldTarget = handlerList[i].target;
            if (oldHandler === handler && oldTarget === target) {
                handlerList.splice(i, 1);
                break;
            }
        }
    }

    public clear(target: any) {
        for (let eventName in this.handlers) {
            let handlerList = this.handlers[eventName];
            for (var i = 0; i < handlerList.length; i++) {
                var oldTarget = handlerList[i].target;
                if (oldTarget === target) {
                    handlerList.splice(i, 1);
                }
            }
        }
    }

    public clearAll() {
        this.handlers = {}
    }


    public addBtnEvent(parentNode: cc.Node, objectNode: cc.Node, scriptName: string, eventName: string, data: any = null, isAddEffect: boolean = false) {
        let btn: cc.Button = objectNode.addComponent(cc.Button);
        let clickEventHandler: cc.Component.EventHandler = new cc.Component.EventHandler();
        clickEventHandler.target = parentNode; //这个 node 节点是你的事件处理代码组件所属的节点
        clickEventHandler.component = scriptName;//这个是代码文件名
        clickEventHandler.handler = eventName;
        clickEventHandler.customEventData = data;
        btn.clickEvents.push(clickEventHandler);
        if (isAddEffect) {
            this.addBtnEffect(objectNode);
        }
    }

    public removeBtnEvent(objectNode: cc.Node) {
        objectNode.removeComponent(cc.Button)
    }

    public removeBtnEffect(objectNode: cc.Node) {
        let b: cc.Button = objectNode.getComponent(cc.Button);
        b.transition = cc.Button.Transition.NONE;
    }

    public addBtnEffect(objectNode: cc.Node, scale: number = 1.1) {
        let b = objectNode.getComponent(cc.Button);
        b.transition = cc.Button.Transition.SCALE;
        b.zoomScale = scale;
    }
}
